package com.netease.nieweb.emarket.lottery.service;


import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netease.nieweb.emarket.common.LotteryCommonConstants;
import com.netease.nieweb.emarket.entity.ActivityConfig;
import com.netease.nieweb.emarket.entity.AwardRecord;
import com.netease.nieweb.emarket.entity.LotteryConfig;
import com.netease.nieweb.emarket.lottery.mq.IMessageProvider;
import com.netease.nieweb.emarket.service.ActivityConfigService;
import com.netease.nieweb.emarket.service.AwardRecordService;
import com.netease.nieweb.emarket.service.LotteryConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 　* @Description: TODO
 * 　* @author qiyu
 * 　* @date 2020/12/15 15:07
 *
 */
@Service(value="defaultLotteryService")
@EnableBinding(Sink.class)
@Slf4j
public class DefaultLotteryService extends AbstractLotteryService {

    @Autowired
    private LotteryConfigService lotteryConfigService;

    @Autowired
    private AwardRecordService awardRecordService;

    @Autowired
    private ActivityConfigService activityConfigService;

    @Autowired
    private ApplicationEventPublisher publisher;


    @Resource
    private IMessageProvider messageProvider;


    @Override
    public boolean validate(String activityId) {
        return false;
    }

    /**
     * 库存初始化
     * 兜底奖励必须排在最后
     */
    @Override
    public void initStock() {

        List<ActivityConfig> currentActivity = getCurrentActivity();

        /*遍历活动初始化数据*/
        for (ActivityConfig activity : currentActivity) {
            String act=activity.getId();
            /*查询奖品信息，兜底奖励必须排在最后*/
            List<LotteryConfig> lotteryConfigs = getLotteryConfig(act);

            if(CollectionUtils.isEmpty(lotteryConfigs))
            {
                continue;
            }

            /*初始化各变量*/
            String key=act+"DEFAULT_LOTTERY_STOCK";
            LOTTERY_KEY.put(act,key);
            prize.put(act,new ArrayList<>());
            stocks.put(act,new ArrayList<>());
            sum.put(act,0);
            thankMin.put(act,0);
            prizeProbability.put(act,new ArrayList<>());
            zeroStock.put(act,false);

            //当前还有库存的奖品数
            int hasStockCount=0;

            /*遍历奖品表，进行数据初始化*/
            for (LotteryConfig config : lotteryConfigs) {
                prize.get(act).add(config.getId());
                int currentStock=getCurrentStock(config.getId(),act);
                if(config.getStock()-currentStock>0)
                {
                    hasStockCount++;
                }
                stocks.get(act).add(config.getStock()-currentStock);
                int tmpSum=sum.get(act)+config.getProbability();
                sum.put(act,tmpSum);
                prizeProbability.get(act).add(tmpSum);
                stringRedisTemplate.opsForHash().put(key,config.getId(),currentStock+"");
                if(config.getStock()>0)
                {
                    /*无限次数的奖励为兜底奖励，库存为-1*/
                    int tmpThankMin=thankMin.get(act)+config.getProbability();
                    thankMin.put(act,tmpThankMin);
                }
                lotteryConfigMap.put(config.getId(),config);
            }

            /*判断活动是否已经没有库存*/
            if(hasStockCount==0)
            {
                zeroStock.put(act,true);
            }
        }
    }

    /**
     * 根据id获取当前中奖记录数
     * @return
     */
    public int getCurrentStock(String id, String activityId)
    {
        QueryWrapper<AwardRecord> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(AwardRecord::getActivityId,activityId)
                .eq(AwardRecord::getPrizeId,id);
        return  awardRecordService.count(queryWrapper);
    }

    /**
     * 插入中奖记录
     * @param id
     * @return
     */
    @Override
    public String addAwardRecord(String id, String activityId) {
        messageProvider.send(id,activityId);
        return "";
    }

    @StreamListener(Sink.INPUT)
    public void input(Message<JSONObject> record){
        JSONObject payload = record.getPayload();

        LotteryConfig lotteryConfig =lotteryConfigMap.get(payload.getString("id"));
        AwardRecord awardRecord=new AwardRecord();
        awardRecord.setPrizeId(lotteryConfig.getId());
        awardRecord.setPrizeName(lotteryConfig.getPrizeName());
        awardRecord.setPrizeType(lotteryConfig.getPrizeType());
        awardRecord.setStatus(LotteryCommonConstants.AWARD_STATUS_WAIT);
        awardRecord.setActivityId(payload.getString("activityId"));
        awardRecord.setOtherJson(lotteryConfig.getOtherJson());
        awardRecord.setHandler(lotteryConfig.getHandler());
        awardRecord.setFailTime(0);
        awardRecord.setReqMethod(lotteryConfig.getReqMethod());
        awardRecord.setUserId(IdUtil.simpleUUID());
        awardRecord.setCreateTime(new Date());
        awardRecord.setCreateUserId(IdUtil.simpleUUID());
        awardRecord.setIsTest(1);
        awardRecord.setId(IdUtil.simpleUUID());
        //awardRecordService.save(awardRecord);
    }

    /**
     * 获取当前的抽奖活动
     * @return
     */
    public List<ActivityConfig> getCurrentActivity()
    {
        Date now=new Date();
        QueryWrapper<ActivityConfig> queryWrapper=new QueryWrapper();
        queryWrapper.lambda()
                .lt(ActivityConfig::getBeginTime,now)
                .gt(ActivityConfig::getEndTime,now);
        return activityConfigService.list(queryWrapper);
    }

    /**
     * 获取活动奖品配置
     * @param actId
     * @return
     */
    public List<LotteryConfig> getLotteryConfig(String actId)
    {
        QueryWrapper<LotteryConfig> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(LotteryConfig::getActivityId,actId)
                .eq(LotteryConfig::getStatus,LotteryCommonConstants.LOTTERY_STATUS_USABLE)
                .orderByDesc(LotteryConfig::getStock);
        return lotteryConfigService.list(queryWrapper);
    }

}
